//用户库实现，等价于其他编程语言提供的标准库

#![no_std]
#![feature(linkage)] //为了支持weak 弱链接操作

#[macro_use]
pub mod console;
mod lang_items;
mod syscall;

//用Rust的宏将 _start 这段代码编译后的汇编代码中放在一个名为 .text.entry 的代码段中,
//方便我们在后续链接的时候调整它的位置使得它能够作为用户库的入口。
#[unsafe(no_mangle)]
#[unsafe(link_section = ".text.entry")]
pub extern "C" fn _start() -> ! {
    clear_bss();
    exit(main());
    panic!("unreachable after sys_exit!");
}

// weak 弱链接，由于 lib.rs 中的 main 符号是弱链接，链接器会使用 bin 目录下的应用主逻辑作为 main
#[linkage = "weak"]
#[unsafe(no_mangle)]
fn main() -> i32 {
    panic!("Cannot find main!");
}

fn clear_bss() {
    unsafe extern "C" {
        safe fn start_bss();
        safe fn end_bss();
    }
    (start_bss as usize..end_bss as usize).for_each(|addr| unsafe {
        (addr as *mut u8).write_volatile(0);
    });
}

pub fn write(fd: usize, buf: &[u8]) -> isize {
    syscall::sys_write(fd, buf)
}
pub fn exit(exit_code: i32) -> isize {
    syscall::sys_exit(exit_code)
}
